﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;

namespace Clotho
{
    public class Plot:IItem{
        private readonly Novel nov;
        public Novel Nov => nov;


        public event EventHandler eNameChanged;
        private string name;
        public string Name { get {
                return name; 
			}set {
                if(name == value) {
                    return;
				}
                if(value == "") {
                    throw new InvalidCmd_Exception(this,$"不能将情节【{name}】的标题改为空。");
				}
                if (Nov.Plots.ContainsKey(value)) {
                    throw new InvalidCmd_Exception(this, $"不能将情节【{name}】的名字改为【{value}】，因为后者已经存在。");
                }
                string old = name;
                Nov.doCmd(() => {
                    Nov.renamingPlor(this,value);
                    name = value;
                    eNameChanged?.Invoke(this, EventArgs.Empty); 
                }, () => {
                    Nov.renamingPlor(this, old);
                    name = old;
                    eNameChanged?.Invoke(this, EventArgs.Empty);
                });
            }
        }
        public event EventHandler eDescriptionChanged;
        string description;
        public string Description {
            get {
                return description;
            }
            set {
                string old = description;
                Nov.doCmd(() => {
                    description = value;
                    eDescriptionChanged?.Invoke(this,EventArgs.Empty);
                }, () => {
                    description = old;
                    eDescriptionChanged?.Invoke(this, EventArgs.Empty);
                });
            }
        }
        public List<string> Path => new List<string>(10) { Name } ;
		public List<IFeature> Features { get; private set; } = new List<IFeature>(128);
        internal Plot(Novel n,string title, string desc = "") {
            nov = n;
            name = title;
            description = desc;
            Nov.addPlot(this);
        }
        internal Plot(Novel n, string title, Plot old) {
            nov = n;
            name = title;
            description = old.Description;
            foreach (var feature in old.Features) {
                var new_fea = feature.Clone(this);
                if (new_fea != null) {
                    Features.Add(new_fea as IFeature);
                }
            }
            Nov.addPlot(this);
        }



        public string writeToStr() {
            StringBuilder sb = new StringBuilder();
            sb.Append(IFeature.Level_mark[1].str);
            sb.Append(name);
            sb.Append('\n');
            sb.Append(description);
            foreach (var feature in Features) {
                feature.writeToStr(2, sb);
            }
            return sb.ToString();
        }
        public static Plot readFromStr(Novel n, string str, FeatureFactory ff) {
            int ptr = IFeature.Level_mark[1].len;
            int end = str.IndexOf('\n', ptr);
            if (end == -1) {
                end = str.Length;
            }
            var name = str.Substring(ptr, end - ptr);
            ptr = end+1; 
            end = str.IndexOf('#', ptr);
            Plot p;
            if (end == -1) {
                end = str.Length;
                var description = str.Substring(ptr, end - ptr);
                p = new Plot(n, name, description);
            } else {
                end -= 1;//去掉回车
                var description = str.Substring(ptr, end - ptr);
                p = new Plot(n, name, description);
                IFeature.readAllFeatureFromStr(str.Substring(end),2, ff,p);
            }
            return p;
        }


        public event EventHandler eSelectChange;
        bool selected= false;
        public bool Selected {
            get => selected;
            set {
                if (selected != value) {
                    selected = value;
                    eSelectChange?.Invoke(this, EventArgs.Empty);
                }
            }
		}
        public event EventHandler eRemoved;
        public void onRemoved() {
            eRemoved?.Invoke(this, EventArgs.Empty);
		}



    }
    static public class Plot_expand {

    }


}
